package com.example.myapplicationthirteen;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.util.Log;

import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import java.util.HashMap;
import java.util.Map;

/**
 * 广播管理器 - 严格按照广播分类逻辑设计
 * 
 * 1. 按传播方式分类：
 *    - 普通广播：异步执行，所有接收器同时接收，无法截断，无法修改数据
 *    - 有序广播：同步执行，按优先级顺序接收，可以截断，可以修改数据
 * 
 * 2. 按作用范围分类：
 *    - 全局广播：系统范围内传播，可能被其他应用接收
 *    - 本地广播：仅应用内传播，更安全高效
 * 
 * 核心原则："能用地播不用全局，能动态注册不用静态"（兼顾安全与性能）
 * 避坑点：自动处理Android 8.0+隐式广播限制，管理动态注册的接收器生命周期
 */
public class BroadcastManager {
    private static final String TAG = "BroadcastManager";
    private static BroadcastManager instance;
    
    // 广播Action常量
    public static final String ACTION_NORMAL_BROADCAST = "com.example.myapplicationthirteen.ACTION_NORMAL_BROADCAST";
    public static final String ACTION_ORDERED_BROADCAST = "com.example.myapplicationthirteen.ACTION_ORDERED_BROADCAST";
    public static final String ACTION_LOCAL_BROADCAST = "com.example.myapplicationthirteen.ACTION_LOCAL_BROADCAST";
    public static final String ACTION_LOGIN_SUCCESS = "com.example.myapplicationthirteen.ACTION_LOGIN_SUCCESS";
    
    // 权限常量
    public static final String PERMISSION_RECEIVE_BROADCAST = "com.example.myapplicationthirteen.permission.RECEIVE_BROADCAST";
    
    private Context context;
    private LocalBroadcastManager localBroadcastManager;
    private Map<BroadcastReceiver, IntentFilter> registeredReceivers; // 记录已注册的接收器

    /**
     * 单例模式获取实例
     * @param context 上下文（建议使用Application Context避免内存泄漏）
     * @return BroadcastManager实例
     */
    public static synchronized BroadcastManager getInstance(Context context) {
        if (instance == null) {
            // 使用Application Context，避免内存泄漏
            instance = new BroadcastManager(context.getApplicationContext());
        }
        return instance;
    }

    /**
     * 私有构造函数
     * @param context 应用上下文
     */
    private BroadcastManager(Context context) {
        this.context = context;
        this.localBroadcastManager = LocalBroadcastManager.getInstance(context);
        this.registeredReceivers = new HashMap<>();
    }

    /**
     * 【传播方式】发送普通广播（异步）
     * 特性：异步执行，所有接收器同时接收，无法截断，无法修改数据
     * 适用场景：事件通知、状态变更等不需要同步处理的场景
     * @param action 广播Action
     * @param data 广播数据
     */
    public void sendNormalBroadcast(String action, String data) {
        try {
            Intent intent = createIntent(action, data);
            context.sendBroadcast(intent);
            Log.d(TAG, "发送普通全局广播: " + action);
        } catch (Exception e) {
            Log.e(TAG, "发送普通全局广播失败: " + e.getMessage(), e);
        }
    }

    /**
     * 【传播方式】发送带权限的普通广播（异步）
     * 特性：异步执行，受权限保护，增加安全性
     * 适用场景：需要权限控制的全局事件通知
     * @param action 广播Action
     * @param data 广播数据
     * @param permission 权限
     */
    public void sendNormalBroadcast(String action, String data, String permission) {
        try {
            Intent intent = createIntent(action, data);
            
            if (permission != null) {
                context.sendBroadcast(intent, permission);
            } else {
                context.sendBroadcast(intent);
            }
            Log.d(TAG, "发送普通全局广播: " + action + (permission != null ? " (带权限)" : ""));
        } catch (Exception e) {
            Log.e(TAG, "发送普通全局广播失败: " + e.getMessage(), e);
        }
    }

    /**
     * 【传播方式】发送有序广播（同步）
     * 特性：同步执行，按优先级顺序接收，可以截断，可以修改数据
     * 适用场景：需要链式处理、数据修改或流程控制的场景
     * @param action 广播Action
     * @param data 广播数据
     */
    public void sendOrderedBroadcast(String action, String data) {
        try {
            Intent intent = createIntent(action, data);
            // 对于有序广播，我们需要一个结果接收器（可以为null）
            context.sendOrderedBroadcast(intent, null, null, null, 0, null, null);
            Log.d(TAG, "发送有序全局广播: " + action);
        } catch (Exception e) {
            Log.e(TAG, "发送有序全局广播失败: " + e.getMessage(), e);
        }
    }

    /**
     * 【作用范围】发送本地广播（应用内）
     * 特性：仅应用内传播，更安全，更高效，异步执行
     * 适用场景：应用内部组件间通信，如UI更新、状态同步等
     * @param action 广播Action
     * @param data 广播数据
     */
    public void sendLocalBroadcast(String action, String data) {
        try {
            Intent intent = createIntent(action, data);
            localBroadcastManager.sendBroadcast(intent);
            Log.d(TAG, "发送本地广播: " + action);
        } catch (Exception e) {
            Log.e(TAG, "发送本地广播失败: " + e.getMessage(), e);
        }
    }

    /**
     * 【传播方式+作用范围】发送同步本地广播（应用内+同步）
     * 特性：仅应用内传播，同步执行（相当于本地有序广播）
     * 适用场景：需要应用内同步处理的广播，如组件间同步状态变更
     * @param action 广播Action
     * @param data 广播数据
     */
    public void sendOrderedLocalBroadcast(String action, String data) {
        try {
            Intent intent = createIntent(action, data);
            localBroadcastManager.sendBroadcastSync(intent);
            Log.d(TAG, "发送同步本地广播: " + action);
        } catch (Exception e) {
            Log.e(TAG, "发送同步本地广播失败: " + e.getMessage(), e);
        }
    }

    /**
     * 【作用范围】注册全局广播接收器（系统级）
     * 特性：接收系统范围内的广播，需在组件销毁时手动注销
     * 适用场景：需要接收系统事件或与其他应用交互的场景
     * @param receiver 广播接收器
     * @param action 广播Action
     * @param priority 优先级（有序广播使用）
     * @return 是否注册成功
     */
    public boolean registerGlobalReceiver(BroadcastReceiver receiver, String action, int priority) {
        try {
            if (receiver == null || action == null) {
                Log.e(TAG, "接收器或Action不能为空");
                return false;
            }

            // 检查是否已注册
            if (isReceiverRegistered(receiver)) {
                Log.w(TAG, "接收器已注册，不重复注册");
                return false;
            }

            IntentFilter intentFilter = createIntentFilter(action, priority);
            context.registerReceiver(receiver, intentFilter);
            registeredReceivers.put(receiver, intentFilter);
            Log.d(TAG, "注册全局广播接收器成功: " + action + ", 优先级: " + priority);
            return true;
        } catch (Exception e) {
            Log.e(TAG, "注册全局广播接收器失败: " + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 【作用范围】注册本地广播接收器（应用内，推荐使用）
     * 特性：仅接收应用内广播，无需考虑权限，更安全高效
     * 适用场景：应用内部组件间通信
     * @param receiver 广播接收器
     * @param action 广播Action
     * @return 是否注册成功
     */
    public boolean registerLocalReceiver(BroadcastReceiver receiver, String action) {
        try {
            if (receiver == null || action == null) {
                Log.e(TAG, "接收器或Action不能为空");
                return false;
            }

            // 检查是否已注册
            if (isReceiverRegistered(receiver)) {
                Log.w(TAG, "接收器已注册，不重复注册");
                return false;
            }

            IntentFilter intentFilter = new IntentFilter(action);
            localBroadcastManager.registerReceiver(receiver, intentFilter);
            registeredReceivers.put(receiver, intentFilter);
            Log.d(TAG, "注册本地广播接收器成功: " + action);
            return true;
        } catch (Exception e) {
            Log.e(TAG, "注册本地广播接收器失败: " + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 【作用范围】注册带多个Action的本地广播接收器
     * 特性：一个接收器可处理多种Action的应用内广播
     * 适用场景：组件需要响应多个相关事件的场景
     * @param receiver 广播接收器
     * @param actions 广播Actions数组
     * @return 是否注册成功
     */
    public boolean registerLocalReceiver(BroadcastReceiver receiver, String[] actions) {
        try {
            if (receiver == null || actions == null || actions.length == 0) {
                Log.e(TAG, "接收器或Actions不能为空");
                return false;
            }

            // 检查是否已注册
            if (isReceiverRegistered(receiver)) {
                Log.w(TAG, "接收器已注册，不重复注册");
                return false;
            }

            IntentFilter intentFilter = new IntentFilter();
            for (String action : actions) {
                if (action != null) {
                    intentFilter.addAction(action);
                }
            }
            localBroadcastManager.registerReceiver(receiver, intentFilter);
            registeredReceivers.put(receiver, intentFilter);
            Log.d(TAG, "注册多Action本地广播接收器成功");
            return true;
        } catch (Exception e) {
            Log.e(TAG, "注册多Action本地广播接收器失败: " + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 注销指定的广播接收器
     * @param receiver 广播接收器
     * @return 是否注销成功
     */
    public boolean unregisterReceiver(BroadcastReceiver receiver) {
        try {
            if (receiver == null || !isReceiverRegistered(receiver)) {
                Log.e(TAG, "接收器不存在或未注册");
                return false;
            }

            // 尝试在本地和全局都注销（安全起见）
            try {
                localBroadcastManager.unregisterReceiver(receiver);
            } catch (Exception e) {
                // 忽略异常，可能不是本地广播接收器
            }
            
            try {
                context.unregisterReceiver(receiver);
            } catch (Exception e) {
                // 忽略异常，可能不是全局广播接收器
            }
            
            registeredReceivers.remove(receiver);
            Log.d(TAG, "注销广播接收器成功");
            return true;
        } catch (Exception e) {
            Log.e(TAG, "注销广播接收器失败: " + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 注销所有已注册的广播接收器
     * 在组件销毁时调用此方法，确保没有接收器泄漏
     */
    public void unregisterAllReceivers() {
        try {
            for (BroadcastReceiver receiver : registeredReceivers.keySet()) {
                unregisterReceiver(receiver);
            }
            registeredReceivers.clear();
            Log.d(TAG, "注销所有广播接收器成功");
        } catch (Exception e) {
            Log.e(TAG, "注销所有广播接收器失败: " + e.getMessage(), e);
        }
    }

    /**
     * 检查接收器是否已注册
     * @param receiver 广播接收器
     * @return 是否已注册
     */
    public boolean isReceiverRegistered(BroadcastReceiver receiver) {
        return receiver != null && registeredReceivers.containsKey(receiver);
    }

    /**
     * 创建Intent对象，自动处理Android 8.0+的隐式广播限制
     * 避坑点：Android 8.0+对隐式广播进行了限制，需要设置包名
     * @param action 广播Action
     * @param data 广播数据
     * @return Intent对象
     */
    private Intent createIntent(String action, String data) {
        Intent intent = new Intent(action);
        
        // Android 8.0+ 隐式广播限制处理：设置包名
        // 对于全局广播，需要设置包名来绕过限制
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            intent.setPackage(context.getPackageName());
        }
        
        // 添加数据
        if (data != null) {
            intent.putExtra("data", data);
        }
        
        return intent;
    }

    /**
     * 创建IntentFilter对象
     * @param action 广播Action
     * @param priority 优先级
     * @return IntentFilter对象
     */
    private IntentFilter createIntentFilter(String action, int priority) {
        IntentFilter intentFilter = new IntentFilter(action);
        intentFilter.setPriority(priority);
        return intentFilter;
    }
}